package com.ruoyi.feike.instener;
import java.util.Date;

import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Maps;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.feike.controller.PdfController;
import com.ruoyi.feike.domain.*;
import com.ruoyi.feike.mapper.*;
import com.ruoyi.feike.service.IProposalByCommericalAndMarketingService;
import com.ruoyi.feike.service.impl.BasicInformationServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.poi.hssf.record.DVALRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.*;
@Slf4j
public class ReportDepositListener implements ExecutionListener {

    @Autowired
    private ReportDepositMapper reportDepositMapper;
    @Autowired
    private TaskService taskService;
    @Autowired
    private DealerInformationMapper dealerInformationMapper;
    @Autowired
    private DepositCalculationMapper depositCalculationMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private BasicInformationMapper basicInformationMapper;
    @Autowired
    private LimitActiveProposalMapper limitActiveProposalMapper;

    private static final String REPORT_DEPOSIT = "zx:report_deposit:";

    @Value("${wfs.url}")
    private String wfsUrl;

    private Expression state;

    @Override
    public void notify(DelegateExecution delegateExecution) {
        String instanceId = delegateExecution.getProcessInstanceBusinessKey();
        // 根据instanceId 查询dealerCode 取首个dealercode
        ProposalByCommericalAndMarketing proposalByCommericalAndMarketing = new ProposalByCommericalAndMarketing();
        proposalByCommericalAndMarketing.setInstanceId(instanceId);
        List<LimitActiveProposal> listByInstanceId1 = SpringUtils.getBean(LimitActiveProposalMapper.class).getListByInstanceId(instanceId);
        if(CollectionUtils.isEmpty(listByInstanceId1)){
            log.info("当前实例对应节点数据不存在,instanceId={}",instanceId);
            return;
        }
        String dealerCode = listByInstanceId1.get(0).getDealerCode();
        if(StringUtils.isEmpty(dealerCode)){
            log.info("当前实例对应节点数据不存在,instanceId={},dealerCode={}",instanceId,dealerCode);
        }

        String[] dealerCodeArr = new String[1];
        dealerCodeArr[0] = dealerCode;
        List<String[]> dealerCodeArrList = new ArrayList<>();
        dealerCodeArrList.add(dealerCodeArr);
        // 根据DM OP节点设置 approvalPoint 1 DM节点 2 OP节点 3 流程已结束
        Integer approvalPoint=Integer.parseInt(state.getValue(delegateExecution).toString());
        // 流程结束 根据instanceId查出报表其他数据
        List<DepositCalculation> listByInstanceId = SpringUtils.getBean(DepositCalculationMapper.class).getListByInstanceId(instanceId);
        List<BasicInformation> basicInformations = SpringUtils.getBean(BasicInformationMapper.class).selectDealerGroupByByInstanceId(instanceId);
        if(CollectionUtils.isEmpty(basicInformations)){
            log.info("basicInformations信息异常");
        }
        Date requestDate = DateUtils.getNowDate();
        // 获取当前oldAmount
        Double balanceAmount = getBalanceAmount(dealerCodeArrList);
        if(approvalPoint==8){
            log.info("DM发起请求,当前时间及请求数据requestDate={},oldBalanceAmount={}",requestDate,balanceAmount);
            listByInstanceId.forEach(
                    instance->{
                        ReportDeposit report = new ReportDeposit();
                        report.setId(IdUtils.simpleUUID());
                        report.setInstanceId(instanceId);
                        report.setDealerCode(listByInstanceId1.get(0).getDealerCode());
                        report.setDealerName(listByInstanceId1.get(0).getDealerName());
                        report.setRequestDate(new Date());
                        report.setRequestType(instance.getProcess());
                        report.setDepositType(instance.getLimitType());
                        if(StringUtils.isNotEmpty(instance.getGap())){
                            report.setRequestAmount(instance.getGap().contains("-")?instance.getTransferAmount():instance.getGap());
                        }
                        report.setTransferToDealerCode(instance.getTransferTo());
                        report.setTransferToDealerName(instance.getTransferTo());
                        report.setOldBalanceAmount(balanceAmount.toString());
                        report.setGroupNameCn(basicInformations.get(0).getGroupNameCN());
                        report.setGroupNameEn(basicInformations.get(0).getGroupNameEN());
                        report.setCreateTime(new Date());
                        report.setUpdateTime(new Date());
                        log.info("DM此时的对象reportDeposit={}",report);
                        SpringUtils.getBean(ReportDepositMapper.class).insertReportDeposit(report);
                    });
            return;
        }
        if(approvalPoint==9){
            List<ReportDeposit> msgByInstanceId = SpringUtils.getBean(ReportDepositMapper.class).getMsgByInstanceId(instanceId);
            if(CollectionUtils.isEmpty(msgByInstanceId)){
                log.info("op计算异常");
                return;
            }
            ReportDeposit reportDeposit1 = msgByInstanceId.get(0);
            // 删除原有数据加入新数据
            SpringUtils.getBean(ReportDepositMapper.class).deleteByInstanceId(instanceId);
            listByInstanceId.forEach(
                    instance->{
                        ReportDeposit report = new ReportDeposit();
                        report.setId(IdUtils.simpleUUID());
                        report.setInstanceId(instanceId);
                        report.setDealerCode(reportDeposit1.getDealerCode());
                        report.setDealerName(reportDeposit1.getDealerName());
                        report.setRequestDate(reportDeposit1.getRequestDate());
                        report.setProcessingDate(new Date());
                        report.setRequestType(instance.getProcess());
                        report.setDepositType(instance.getLimitType());
                        report.setRequestAmount(com.ruoyi.common.utils.StringUtils.isNotEmpty(instance.getGap())&&instance.getGap().contains("-")?instance.getTransferAmount():instance.getGap());
                        report.setTransferToDealerCode(instance.getTransferTo());
                        report.setTransferToDealerName(instance.getTransferTo());
                        report.setOldBalanceAmount(reportDeposit1.getOldBalanceAmount());
                        report.setNewBalanceAmount(balanceAmount.toString());
                        report.setGroupNameCn(basicInformations.get(0).getGroupNameCN());
                        report.setGroupNameEn(basicInformations.get(0).getGroupNameEN());
                        report.setCreateTime(new Date());
                        report.setUpdateTime(new Date());
                        log.info("OP此时的对象reportDeposit={}",report);
                        SpringUtils.getBean(ReportDepositMapper.class).insertReportDeposit(report);
                    });
            return;
        }
        if(approvalPoint==10) {
            // 流程结束 根据instanceId查出报表其他数据
            List<ReportDeposit> msgByInstanceId = SpringUtils.getBean(ReportDepositMapper.class).getMsgByInstanceId(instanceId);
            if (CollectionUtils.isEmpty(msgByInstanceId)) {
                log.info("op计算异常");
                return;
            }

            ReportDeposit reportDeposit1 = msgByInstanceId.get(0);
            // 删除原有数据加入新数据
            SpringUtils.getBean(ReportDepositMapper.class).deleteByInstanceId(instanceId);
            listByInstanceId.forEach(
                    instance -> {
                        ReportDeposit report = new ReportDeposit();
                        report.setId(IdUtils.simpleUUID());
                        report.setInstanceId(instanceId);
                        report.setDealerCode(reportDeposit1.getDealerCode());
                        report.setDealerName(reportDeposit1.getDealerName());
                        report.setRequestDate(reportDeposit1.getRequestDate());
                        report.setProcessingDate(new Date());
                        report.setRequestType(instance.getProcess());
                        report.setDepositType(instance.getLimitType());
                        report.setRequestAmount(instance.getGap().contains("-") ? instance.getTransferAmount() : instance.getGap());
                        report.setTransferToDealerCode(instance.getTransferTo());
                        // 根据dealerCode获取dealerName
                        List<DealerInformation> dealerNameByCode = SpringUtils.getBean(DealerInformationMapper.class).getDealerNameByCode(instance.getTransferTo());
                        report.setTransferToDealerName(CollectionUtils.isEmpty(dealerNameByCode)?instance.getTransferTo():dealerNameByCode.get(0).getDealerName());
                        report.setOldBalanceAmount(reportDeposit1.getOldBalanceAmount());
                        report.setNewBalanceAmount(balanceAmount.toString());
                        report.setGroupNameCn(basicInformations.get(0).getGroupNameCN());
                        report.setGroupNameEn(basicInformations.get(0).getGroupNameEN());
                        report.setCreateTime(new Date());
                        report.setUpdateTime(new Date());
                        log.info("结束此时的对象reportDeposit={}", report);
                        SpringUtils.getBean(ReportDepositMapper.class).insertReportDeposit(report);
                    });
            // 流程结束报表report_insurance-1
            List<ReportInsurance> list = SpringUtils.getBean(SelfplanInformationMapper.class).selectInformationByInstanceId(instanceId);
            List<ReportInsurance> list2 = SpringUtils.getBean(NewSumMapper.class).selectInformationByInstanceId(instanceId);
            List<ReportInsurance> list3 = SpringUtils.getBean(PaidSumMapper.class).selectInformationByInstanceId(instanceId);
            list.addAll(list2);
            list.addAll(list3);
            if(CollectionUtils.isEmpty(list)){
                log.info("Report insurance 数据为空");
                return;
            }
            // 填充数据
            list.forEach(data->{
                data.setCreateTime(new Date());
                data.setUpdateTime(new Date());
                SpringUtils.getBean(ReportInsuranceMapper.class).insertReportInsurance(data);
            });
        }

    }

    public double getBalanceAmount(List<String[]> dealerCode){
        double balance = 0.0d;
        JSONObject jsonObject = new JSONObject();
        Map<String, Object> result = new HashMap<>();
        jsonObject.put("DealerCode", dealerCode);
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost2 = new HttpPost(wfsUrl + "SuspenseInfo");
        //HttpPost httpPost2 = new HttpPost("http://uat.fcagroupafc.com:7677/CreditLoanSuspenseAPIUAT7/" + "SuspenseInfo");
        httpPost2.addHeader("Content-Type", "application/json;charset=UTF-8");
        StringEntity entity = new StringEntity(jsonObject.toString(), "utf-8");
        entity.setContentType("application/json;charset=UTF-8");
        entity.setContentEncoding("UTF-8");
        httpPost2.setEntity(entity);
        httpPost2.setHeader("Accept", "application/json, text/plain, */*");
        httpPost2.setHeader("Accept-Encoding", "gzip, deflate");
        httpPost2.setHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6");
        httpPost2.setHeader("Connection", "keep-alive");
        httpPost2.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 Edg/93.0.961.38");
        Map<String, Object> objectList = new HashMap<>();
        Map<String, Object> objectList2 = new HashMap<>();
        try {
            HttpResponse response2 = httpClient.execute(httpPost2);
            String responseStr2 = EntityUtils.toString(response2.getEntity());
            log.info("WFS外部接口数据返回结果=[{}]", responseStr2);
            objectList2 = JSONObject.parseObject(responseStr2, Map.class);
            if (StringUtils.equals("200",objectList2.get("Code").toString())) {
                JSONArray data = JSONObject.parseArray(objectList2.get("Data").toString());
                JSONArray objects = JSONObject.parseArray(data.get(0).toString());
                Object suspenseInfo1 = JSONObject.parseObject(objects.get(0).toString()).get("SuspenseInfo");
                JSONObject jsonObject1 = JSONObject.parseObject(suspenseInfo1.toString());
                String cbDeposit = String.valueOf(jsonObject1.get("CBDeposit"));
                String nonRefundDeposit = String.valueOf(jsonObject1.get("NonRefundDeposit"));
                String deposit = String.valueOf(jsonObject1.get("Deposit"));
                String tierCashDeposit = String.valueOf(jsonObject1.get("2ndTierCashDeposit"));
                log.info("接口返回值cbDeposit={},nonRefundDeposit={},deposit={},tierCashDeposit={}",cbDeposit,nonRefundDeposit,deposit,tierCashDeposit);
                double balance1 = StringUtils.isBlank(cbDeposit)?0:Double.parseDouble(cbDeposit);
                double balance2 = StringUtils.isBlank(nonRefundDeposit)?0:Double.parseDouble(nonRefundDeposit);
                double balance3 = StringUtils.isBlank(deposit)?0:Double.parseDouble(deposit);
                double balance4 = StringUtils.isBlank(tierCashDeposit)?0:Double.parseDouble(tierCashDeposit);
                return balance1+balance2+balance3+balance4;
            }
        } catch (Exception e) {
            log.error("调用第三方接口获取balance值异常",e);
            return balance;
        }
        return balance;

    }
}
